package com.wnxy.admin.listener;

/*
 *  故障消息监听器
 * */

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rabbitmq.client.Channel;
import com.wnxy.admin.config.MessageQueueConfig;
import com.wnxy.admin.entity.AlarmMessages;
import com.wnxy.admin.entity.AlarmSettings;
import com.wnxy.admin.service.IAlarmMessagesService;
import com.wnxy.admin.service.IAlarmSettingsService;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.Map;

@Component
@RequiredArgsConstructor
public class FaultInformationListener {

    private final IAlarmSettingsService alarmSettingsServiceImpl;
    private final IAlarmMessagesService alarmMessagesServiceImpl;
    private final RabbitTemplate rabbitTemplate;

    /**
     * 监听故障消息队列并发布消息
     *
     * @param msg 充电桩id，故障等级,故障报警时间，充电桩名称，所属充电站
     */
    @RabbitListener(queues = MessageQueueConfig.FAULT_QUEUE)
    public void handlerFaultMessage(Map<String, Object> msg, Channel channel,
                                    @Header(AmqpHeaders.DELIVERY_TAG) Long deliveryTag) throws IOException {

        Long id = (Long) msg.get("id");
        Integer level = (Integer) msg.get("level");
        String chargingPileName = (String) msg.get("chargingPileName");
        String chargingStationName = (String) msg.get("chargingStationName");
        Date alarmTime = (Date) msg.get("alarmTime");

        try {
            // 根据id,level查找对应的报警设置
            AlarmSettings alarmSettings = alarmSettingsServiceImpl.getOne(Wrappers.lambdaQuery(AlarmSettings.class)
                    .eq(AlarmSettings::getChargerId, id)
                    .eq(AlarmSettings::getAlarmLevel, level));

            //设置报警消息属性
            AlarmMessages alarmMessages = new AlarmMessages();
            alarmMessages.setAlarmType(alarmSettings.getAlarmName());
            alarmMessages.setChargerName(chargingPileName);
            alarmMessages.setStationName(chargingStationName);
            alarmMessages.setAlarmTime(alarmTime);
            alarmMessages.setLevelDegree(level);

            Long expirationTime;
            // 判断报警设置的状态是否启用
            if (!ObjectUtils.isEmpty(alarmSettings) && alarmSettings.getAlarmLevel() == -1) {
                // 严重等级，立即生成报警消息
                alarmMessagesServiceImpl.save(alarmMessages);
                //向延迟交换机发送消息
                expirationTime = 1L; // 1毫秒
                rabbitTemplate.convertAndSend(MessageQueueConfig.DELAY_SWITCH, MessageQueueConfig.ROUTING_KEY,
                        JSONUtil.toJsonStr(alarmMessages), message -> {
                            message.getMessageProperties().setHeader("x-delay", expirationTime);
                            return message;
                        });
                // 确认消息
                channel.basicAck(deliveryTag, false);
            } else if (alarmSettings.getStatus() == 1) {
                // 紧急、一般，报警设置状态为启用，生成报警消息
                alarmMessagesServiceImpl.save(alarmMessages);

                if(alarmSettings.getAlarmLevel() == 0) {
                    //向延迟交换机发送消息/紧急报警设置
                    expirationTime = MessageQueueConfig.EXPIRATION_TIME;
                    rabbitTemplate.convertAndSend(MessageQueueConfig.DELAY_SWITCH, MessageQueueConfig.ROUTING_KEY,
                            JSONUtil.toJsonStr(alarmMessages), message -> {
                                message.getMessageProperties().setHeader("x-delay", expirationTime);
                                return message;
                            });
                }
                // 确认消息
                channel.basicAck(deliveryTag, false);
            } else {
                // 否定消息
                channel.basicNack(deliveryTag, false, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 处理异常，Nack
            channel.basicNack(deliveryTag, true, false);
            // 记录日志或其他操作 TODO
        }
    }
}
